/**
 *	@file	an_puzzle_main.c
 *	@brief	アンノーンパズルメイン
 *	@author	Miyuki Iwasawa
 *	@date	08.06.11
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "gflib/touchpanel.h"
#include "poketool/pokeicon.h"
#include "poketool/monsno.h"
#include "msgdata/msg.naix"
#include "communication/communication.h"

#include "field/sysflag.h"
#include "field/eventflag.h"
#include "savedata/config.h"
#include "application/an_puzzle.h"
#include "an_puzzle_sys.h"
#include "an_puzzle_sub.h"




//=========================================================
//プロトタイプ
//=========================================================
static void an_puzzle_ViewClear(void);
static void an_puzzle_InitData(AN_PUZZLE_WK* wk);
static void an_puzzle_EndData(AN_PUZZLE_WK* wk);

static BOOL app_Init(AN_PUZZLE_WK* wk);
static BOOL app_End(AN_PUZZLE_WK* wk);
static int seq_FadeIn(AN_PUZZLE_WK* wk);
static int seq_FadeOut(AN_PUZZLE_WK* wk);
static int seq_PuzzleMain(AN_PUZZLE_WK* wk);
static int seq_MoveCheck(AN_PUZZLE_WK* wk);
static int seq_Move(AN_PUZZLE_WK* wk);
static int seq_RotEffect(AN_PUZZLE_WK* wk);
static int seq_EndCheck(AN_PUZZLE_WK* wk);
static int seq_PerfectEffect(AN_PUZZLE_WK* wk);



//=========================================================
//プロセス定義
//=========================================================
/**
 *	@brief	アンノーンパズル呼び出し
 */
PROC_RESULT AnPuzzleProc_Init(PROC* proc,int* seq)
{

	switch(*seq){
	case 0:
		an_puzzle_ViewClear();

		//ヒープ作成
		HeapStatePush();
		sys_CreateHeap(HEAPID_BASE_APP,HEAPID_AN_PUZZLE,0x20000);

		{
			AN_PUZZLE_WK* wk = NULL;
			wk = PROC_AllocWork(proc,sizeof(AN_PUZZLE_WK),HEAPID_AN_PUZZLE);
			MI_CpuClear8(wk,sizeof(AN_PUZZLE_WK));

			wk->heapID = HEAPID_AN_PUZZLE;
			wk->param = (AN_PUZZLE_PARAM*)PROC_GetParentWork(proc);

			// SEバンク読み込み
			Snd_DataSetByScene( SND_SCENE_SUB_SEKIBAN ,0,0 );

			//引継ぎデータ初期化
			an_puzzle_InitData(wk);

		}
		(*seq)++;
		break;
	case 1:
		if(app_Init((AN_PUZZLE_WK*)PROC_GetWork(proc))){
			return PROC_RES_FINISH;
		}
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	アンノーンパズルメイン
 */
PROC_RESULT AnPuzzleProc_Main(PROC* proc,int* seq)
{
	AN_PUZZLE_WK* wk = (AN_PUZZLE_WK*)PROC_GetWork(proc);

	switch(*seq){
	case SEQ_FADE_IN:
		*seq = seq_FadeIn(wk);
		break;
	case SEQ_PUZZLE_MAIN:
		*seq = seq_PuzzleMain(wk);
		break;
	case SEQ_MOVE_CHECK:
		*seq = seq_MoveCheck(wk);
		break;
	case SEQ_MOVE:
		*seq = seq_Move(wk);
		break;
	case SEQ_ROT_EFF:
		*seq = seq_RotEffect(wk);
		break;
	case SEQ_END_CHECK:
		*seq = seq_EndCheck(wk);
		break;
	case SEQ_PERFECT:
		*seq = seq_PerfectEffect(wk);
		break;
	case SEQ_FADE_OUT:
		*seq = seq_FadeOut(wk);
		break;
	case SEQ_EXIT:
		return PROC_RES_FINISH;
	}
	CATS_Draw(wk->pActRes);
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	アンノーンパズル終了
 */
PROC_RESULT AnPuzzleProc_End(PROC* proc,int* seq)
{
	AN_PUZZLE_WK* wk = (AN_PUZZLE_WK*)PROC_GetWork(proc);

	if(!app_End(wk)){
		return PROC_RES_CONTINUE;
	}
	an_puzzle_ViewClear();

	//引継ぎデータ書き戻し
	an_puzzle_EndData(wk);

	//ワーク解放
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(HEAPID_AN_PUZZLE);

	sys_DeleteHeap(HEAPID_AN_PUZZLE);

	return PROC_RES_FINISH;
}

///////////////////////////////////////////////////////////////////////////////
//


/**
 *	@brief	画面初期化
 */
static void an_puzzle_ViewClear(void)
{
	sys_VBlankFuncChange(NULL, NULL);
	sys_HBlankIntrStop();	//HBlank割り込み停止

	GF_Disp_GX_VisibleControlInit();
	GF_Disp_GXS_VisibleControlInit();
	GX_SetVisiblePlane(0);
	GXS_SetVisiblePlane(0);

	WIPE_SetBrightness(WIPE_DISP_MAIN,WIPE_FADE_BLACK);
	WIPE_SetBrightness(WIPE_DISP_SUB,WIPE_FADE_BLACK);
	WIPE_ResetWndMask(WIPE_DISP_MAIN);
	WIPE_ResetWndMask(WIPE_DISP_SUB);
}

/**
 *	@brief	引継ぎデータ初期化
 */
static void an_puzzle_InitData(AN_PUZZLE_WK* wk)
{
	CONFIG* config;

	//キーモード初期化
	wk->key_mode = KeyTouchStatus_CheckTouchOrKey(wk->param->kt_status);

	//コンフィグ
	config = SaveData_GetConfig(wk->param->save);
	wk->msg_spd = CONFIG_GetMsgPrintSpeed(config);
	wk->win_type = CONFIG_GetWindowType(config);
	wk->level = wk->param->level;
}

/**
 *	@brief	引継ぎデータ終了処理
 */
static void an_puzzle_EndData(AN_PUZZLE_WK* wk)
{
	//キーモード書き戻し
	KeyTouchStatus_SetTouchOrKey(wk->param->kt_status,wk->key_mode);

	//完成フラグ書き込み
	if(wk->is_clear){
		SysFlag_AnPuzzleClearSet( SaveData_GetEventWork(wk->param->save), wk->level);
	}
}

/**
 *	@brief	初期化
 *
 */
static BOOL app_Init(AN_PUZZLE_WK* wk)
{
	switch(wk->seq){
	case 0:
		AnPuzzleResInit(wk);
		++wk->seq;
		break;
	case 1:
		AnPuzzleSub_InitialDraw(wk);

		//タッチパネル初期化
		InitTPSystem();
		InitTPNoBuff(1);

		wk->seq = 0;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	終了処理
 *
 */
static BOOL app_End(AN_PUZZLE_WK* wk)
{
	//タッチパネル終了
	StopTP();

	AnPuzzleResRelease(wk);
	return TRUE;
}

/**
 *	@brief	フェードイン
 *
 */
static int seq_FadeIn(AN_PUZZLE_WK* wk)
{
	switch(wk->seq){
	case 0:
		WIPE_SYS_Start(
			WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN,
			WIPE_TYPE_FADEIN, WIPE_FADE_BLACK, WIPE_DEF_DIV, WIPE_DEF_SYNC, wk->heapID);
		wk->seq++;
		break;
	case 1:
		if( !WIPE_SYS_EndCheck()){
			break;
		}
		wk->seq = 0;
		return SEQ_PUZZLE_MAIN;
	}
	return SEQ_FADE_IN;
}

/**
 *	@brief	フェードアウト
 *
 */
static int seq_FadeOut(AN_PUZZLE_WK* wk)
{
	switch(wk->seq){
	case 0:
		WIPE_SYS_Start(
			WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT,
			WIPE_TYPE_FADEOUT, WIPE_FADE_BLACK, WIPE_DEF_DIV, WIPE_DEF_SYNC, wk->heapID);
		wk->seq++;
		break;
	case 1:
		if( !WIPE_SYS_EndCheck()){
			break;
		}
		wk->seq = 0;
		return SEQ_EXIT;
	}
	return SEQ_FADE_OUT;
}


/**
 *	@brief	メイン
 *
 */
static int seq_PuzzleMain(AN_PUZZLE_WK* wk)
{
	return AnPuzzleSub_InputSelect(wk);
}

/**
 *	@brief	パネル動作チェック
 */
static int seq_MoveCheck(AN_PUZZLE_WK* wk)
{
	return AnPuzzleSub_InputMoveCheck(wk);
}

/**
 *	@brief	パネルドラッグ移動
 */
static int seq_Move(AN_PUZZLE_WK* wk)
{
	return AnPuzzleSub_InputMove(wk);
}

/**
 *	@brief	パネル回転エフェクト
 */
static int seq_RotEffect(AN_PUZZLE_WK* wk)
{
	return AnPuzzleSub_PanelRotEffect(wk);
}

/**
 *	@brief	終了チェック
 *
 */
static int seq_EndCheck(AN_PUZZLE_WK* wk)
{
	return AnPuzzleSub_EndCheck(wk);
}

/**
 *	@brief	完成エフェクト
 */
static int seq_PerfectEffect(AN_PUZZLE_WK* wk)
{
	return AnPuzzleSub_PerfectEffect(wk);
}